package com.ai.aichat.config;

import com.ai.aichat.filter.JwtAuthFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

// 入口：定义无状态的过滤器链、URL 授权规则与 CORS
@Configuration
@EnableMethodSecurity
public class JwtSecurityConfig {

    @Bean
    public SecurityFilterChain jwtChain(HttpSecurity http, JwtAuthFilter jwtAuthFilter) throws Exception {
        http
                .csrf(csrf -> csrf.disable())                                        // 无状态 API 关闭 CSRF
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 禁用会话
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/api/auth/login", "/public/**").permitAll()       // 登录与公共资源放行
                        .requestMatchers("/api/aichat/users/register").permitAll()
                        .requestMatchers(HttpMethod.GET, "/admin/**").hasRole("ADMIN")   // 示例：仅 ADMIN 可读 admin 资源
                        .anyRequest().authenticated()                                      // 其余请求需要认证
                )
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class) // 插入 JWT 过滤器
                .cors(Customizer.withDefaults());                                     // 启用 CORS（需提供配置源）
        return http.build();
    }

    // 密码编码器：强烈建议使用 BCrypt
    @Bean
    public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
}